package org.dragonnova.meetingapp.app.service;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.os.Parcelable;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;

import org.dragonnova.meetingapp.R;
import org.dragonnova.meetingapp.core.manager.NetManager;
import org.dragonnova.meetingapp.core.manager.UdpManager;
import org.dragonnova.meetingapp.core.net.SocketUtils;
import org.dragonnova.meetingapp.model.bean.DeviceInfo;
import org.dragonnova.meetingapp.model.bean.MeetingInfo;
import org.dragonnova.meetingapp.model.bean.VoiceInfo;
import org.dragonnova.meetingapp.utils.Constants;
import org.dragonnova.meetingapp.utils.LogUtil;
import org.dragonnova.meetingapp.utils.WifiAutoConnectUtil;

import java.util.List;

/**
 * author hucn
 * Created at 2016/6/1 10:36
 * Email: thinkdata@163.com
 * 用于管理WIFI网络入口
 */
public class WIFIServiceTest extends Service {

    private final static String TAG = WIFIServiceTest.class.getName();
    //当前设备的名称
    private static String hostName = "测试机";
    //连接到固定的路由器的账号密码
    private String UNIQUE_SSID = "";
    private String UNIQUE_PASSWORD = "";

    public final static String KEY_HANDLER_WIFI_CONNECT = "org.dragonnova.meetingapp.action.HANDLER_WIFI_CONNECT";

    /*private String UNIQUE_SSID = "development";
    private String UNIQUE_PASSWORD = "12345678";*/

    //本地IP地址
    private String UDP_CLIENT_IP;
    //本地UDP通信端口
    private final static int CLIENT_SOCKET_PORT = 24535;
    //网络状态广播接收者
    private NetGroupReceiver mNetReceiver = new NetGroupReceiver();
    //WIFI管理
    private WifiManager mWifiManager;
    //网络连接管理
    private ConnectivityManager mConnectivityManager;
    //开启WIFI的功能类
    private WifiAutoConnectUtil mWifiAutoConnectUtil;
    //当前设备的信息
    public static DeviceInfo mLocalDeviceInfo;
    //组网管理和发送信息的管理
    private NetManager mNetManager;
    //记录和响应当前网络的状态变化
    private StateImp mState;
    //BINDER
    private WifiBinder wifiBinder = new WifiBinder();

    /**
     * 处理点击说话
     */
    public class WifiBinder extends Binder {
        /**
         * 发送语音包
         */
        public void sendVoiceData(VoiceInfo voiceInfo) {
            mNetManager.sendVoiceMessage(voiceInfo);
        }

        /**
         * 发送退出消息
         */
        public void sendExit() {
            mNetManager.tryDisGroup();
        }

        /**
         * 语音应答线程发送语音输入请求
         */
        public void requestVoiceStart() {
            mNetManager.requestVoiceStart();
        }

        /**
         * 语音应答线程停止发送语音正在输入的消息，且发送停止消息
         */
        public void requestVoiceStop() {
            mNetManager.requestVoiceStop();
        }

        public void requestVoicePersist() {
            mNetManager.requestVoicePersist();
        }

        /**
         * 提供Service对象
         */
        public WIFIServiceTest getService() {
            return WIFIServiceTest.this;
        }

        /**
         * 改变设备信息中的语言设置
         */
        public void changeLocalLanguage(boolean isCH2EN) {
            if (mLocalDeviceInfo != null) {
                if (isCH2EN) {
                    mLocalDeviceInfo.setLanguage(getString(R.string.language_c).charAt(0));
                } else {
                    mLocalDeviceInfo.setLanguage(getString(R.string.language_e).charAt(0));
                }
            }
        }

        /**
         * 发送到服务端改变服务端deviceinfo中的语言标志
         */
        public void changeServerLanguage(char language) {
            mNetManager.changeServerLanguage(language);
        }

        public void searchDevices() {
            mNetManager.searchDevices();

        }

        public boolean setWifiInfo(String ssid, String passwd) {
            if (!TextUtils.equals(ssid, UNIQUE_SSID) || !TextUtils.equals(passwd, UNIQUE_PASSWORD)) {
                UNIQUE_SSID = ssid;
                UNIQUE_PASSWORD = passwd;
                doWifiRefresh(ssid, passwd, "WAP");
            } else {
                checkWifi();
            }
            return true;
        }

        public void createMeeting(MeetingInfo meetingInfo) {
            mNetManager.createMeeting(meetingInfo);
        }

        public void resetMeeting(MeetingInfo meetingInfo) {
            mNetManager.resetMeeting(meetingInfo);
        }

        public MeetingInfo getMeetingInfo() {
            return mNetManager.getMeetingInfo();
        }

        public void renameDevice(DeviceInfo info) {
            mNetManager.renameDevice(info);
        }

        public void startGroup() {
            if (!mNetManager.isStarted()) {
                mNetManager.start();
            } else {
                mNetManager.stop();
                mNetManager.start();
            }
        }

        public void stopGroup() {
            if (mNetManager.isStarted()) {
                sendExit();
                mNetManager.stop();
            }
        }

        public void setMeetingId(int id) {
            mNetManager.setMeetingId(id);
        }

        public void closeMeeting() {
            mNetManager.closeMeeting();

        }

        public void joinMeeting() {
            mNetManager.joinMeeting();
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        // 初始化参数
        initParam();
        // 加入网络
        // checkWifi();
        // 注册广播
        registerNetReceiver();
        // 启动网络线程，组网、服务SOCKET初始化
        initNetManager();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return Service.START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
        try {
            unregisterReceiver(mNetReceiver);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
        mNetManager.stop();
        mNetManager = null;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        LogUtil.d(TAG, "onUnbind");
        return super.onUnbind(intent);
    }

    @Override
    public IBinder onBind(Intent intent) {
        LogUtil.d(TAG, "onBind");
        return wifiBinder;
    }

    @Override
    public void onRebind(Intent intent) {
        LogUtil.d(TAG, "onRebind");
        super.onRebind(intent);
    }

    /**
     * 初始化变量
     */
    private void initParam() {
        // 初始化网络状态对象
        mState = new NetState();
        // WifiManager
        mWifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
        // ConnectivityManager主要管理和网络连接相关的操作
        mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        // 开启WIFI的功能类
        mWifiAutoConnectUtil = new WifiAutoConnectUtil(mWifiManager);
        // 192.168.1.100/24
        UDP_CLIENT_IP = SocketUtils.convertIntIpAddress(mWifiManager.getConnectionInfo().getIpAddress());
        // 5baa6b96a2e46276
        String mDeviceId = Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID);
        // CC:A2:23:35:F1:68
        //String btMacAddr = BluetoothAdapter.getDefaultAdapter().getAddress();
        String btMacAddr = "00:00:00:00:00:00";
        // HUAWEI P7-L00
        // String btName = BluetoothAdapter.getDefaultAdapter().getName();
        String btName = "null";
        // c:e
        char language = getString(R.string.language_c).charAt(0);

        hostName = Build.MODEL;

        // 设备信息对象
        mLocalDeviceInfo = new DeviceInfo();
        mLocalDeviceInfo.setHostId(mDeviceId);
        mLocalDeviceInfo.setHostName(hostName);
        mLocalDeviceInfo.setBtMacAddr(btMacAddr);
        mLocalDeviceInfo.setBtName(btName);
        mLocalDeviceInfo.setLanguage(language);
        mLocalDeviceInfo.setPort(CLIENT_SOCKET_PORT);
        mLocalDeviceInfo.setWifiAddr(UDP_CLIENT_IP);
    }

    /**
     * 检查当前当的网络连接，如果没有连接，那么刷新网络
     */
    private void checkWifi() {
        //拿到现在的网络信息
        NetworkInfo networkInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        WifiInfo wifiInfo = mWifiManager.getConnectionInfo();

        if ((networkInfo.getState() == NetworkInfo.State.CONNECTED)
                && wifiInfo.getSSID() != null
                && (wifiInfo.getSSID().equalsIgnoreCase("\"" + UNIQUE_SSID + "\"")
                || wifiInfo.getSSID().equalsIgnoreCase(UNIQUE_SSID))) {
            UDP_CLIENT_IP = SocketUtils.convertIntIpAddress(wifiInfo.getIpAddress());
            mLocalDeviceInfo.setWifiAddr(UDP_CLIENT_IP);
            mState.correct();
        } else {
            //如果保存的网络信息不为空
            if (!TextUtils.isEmpty(UNIQUE_SSID)) {
                doWifiRefresh(UNIQUE_SSID, UNIQUE_PASSWORD, "WAP");
            } else {
                LogUtil.e(TAG, "The UUID is null!");
            }
        }
    }

    /**
     * 刷新网络
     */
    private void doWifiRefresh(final String ssid, final String passwd, final String wifiKey) {
        if (TextUtils.equals(wifiKey, "WAP")) {
            mWifiAutoConnectUtil.connect(ssid, passwd, WifiAutoConnectUtil.WifiCipherType.WIFICIPHER_WPA);
        }
    }

    /**
     * 注册广播
     */
    private void registerNetReceiver() {
        mNetReceiver = new NetGroupReceiver();
        registerReceiver(mNetReceiver, getFilter());
    }

    /**
     * 开启网络管理类
     */
    private void initNetManager() {
        mNetManager = new UdpManager(WIFIServiceTest.this, mWifiManager);
    }

    /**
     * 全局广播
     */
    private class NetGroupReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
            WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
            if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                if (networkInfo != null && networkInfo.isConnected()) {
                    ///网络连接
                    if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                        //wifi连接
                        LogUtil.d("Net state", "NET_TYPE_WIFI");
                    } else if (networkInfo.getType() == ConnectivityManager.TYPE_ETHERNET) {
                        //有线网络
                        LogUtil.d("Net state", "NET_TYPE_ETHERNET");
                    } else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
                        //3g网络
                        LogUtil.d("Net state", "NET_TYPE_MOBILE");
                    }
                } else if (networkInfo != null && networkInfo.isAvailable()) {
                    //有网络，但是没有连接
                    LogUtil.d("Net state", "NET_TYPE_AVAILABLE");
                } else {
                    //其他状态
                    LogUtil.d("NEt state", "NET_TYPE_NOT_AVAILABLE");
                }
            } else if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
                int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_DISABLED);
                switch (wifiState) {
                    case WifiManager.WIFI_STATE_DISABLED:
                        LogUtil.d("Wifi state", "DISABLED");
                        mState.disabled();
                        break;
                    case WifiManager.WIFI_STATE_DISABLING:
                        break;
                    case WifiManager.WIFI_STATE_ENABLED:
                        LogUtil.d("Wifi state", "ENABLED");
                        mState.enabled();
                        break;
                    case WifiManager.WIFI_STATE_ENABLING:
                        break;
                    case WifiManager.WIFI_STATE_UNKNOWN:
                        break;
                }
            } else if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
                Parcelable parcelableExtra = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
                if (null != parcelableExtra) {
                    NetworkInfo info = (NetworkInfo) parcelableExtra;
                    switch (info.getState()) {
                        case CONNECTED:
                            // 网络已连接
                            LogUtil.e("Wifi state", "CONNECTED");
                            mState.connected();
                            if (wifiInfo.getSSID() != null && (wifiInfo.getSSID().equalsIgnoreCase("\"" + UNIQUE_SSID + "\"") || wifiInfo.getSSID().equalsIgnoreCase(UNIQUE_SSID))) {
                                LogUtil.e("Wifi state", "CORRECT");
                                LogUtil.e("UDP_CLIENT_IP=" + UDP_CLIENT_IP);
                                String currentIp = SocketUtils.convertIntIpAddress(wifiInfo.getIpAddress());
                                if (currentIp != null && !currentIp.equals(UDP_CLIENT_IP)) {
                                    UDP_CLIENT_IP = currentIp;
                                    mLocalDeviceInfo.setWifiAddr(UDP_CLIENT_IP);
                                }
                                mState.correct();
                            } else {
                                //连接的不是制定的网络
                                LogUtil.e("Wifi state", "INCORRECT");
                                mState.incorrect();
                            }
                            break;
                        case CONNECTING:
                            LogUtil.e("Wifi state", "CONNECTING");
                            mState.connecting();
                            break;
                        case DISCONNECTED:
                            LogUtil.e("Wifi state", "DISCONNECTED");
                            mState.disconnected();
                            break;
                        case DISCONNECTING:
                            LogUtil.e("Wifi state", "DISCONNECTING");
                            break;
                        case SUSPENDED:
                            LogUtil.e("Wifi state", "SUSPENDED");
                            break;
                        case UNKNOWN:
                            LogUtil.e("Wifi state", "UNKNOWN");
                            break;
                        default:
                            break;
                    }
                }
            } else if (intent.getAction().equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
                Boolean state = intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false);
                Log.d(TAG, "NetworkInfo connected Statue: " + state);
            } else if (intent.getAction().equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
                SupplicantState state = intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE);
                Log.d(TAG, "NetworkInfo connected Statue: " + state);
            } else if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
                List<ScanResult> results = mWifiManager.getScanResults();
                for (ScanResult result : results) {
                    Log.d(TAG, "SCAN_RESULTS_AVAILABLE_ACTION " + "BSSID: " + result.BSSID
                            + ", SSID: " + result.SSID);
                }
            }
        }
    }

    /**
     * 监听网络变化的广播
     */
    private IntentFilter getFilter() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        filter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
        filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
        filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        return filter;
    }

    /**
     * 网络状态变更的实现
     */
    private class NetState implements StateImp {
        private NetStatus preNetStatus = NetStatus.UNKNOWN_STATUS;
        private NetStatus netStatus = NetStatus.UNKNOWN_STATUS;

        @Override
        public void disabled() {
            preNetStatus = netStatus;
            netStatus = NetStatus.WIFI_DISABLED_STATUS;
            if (preNetStatus != netStatus) {
                //mNetManager.stop();
                //checkWifi();
            }
        }

        @Override
        public void enabled() {
            netStatus = NetStatus.WIFI_ENABLED_STATUS;
        }

        @Override
        public void connecting() {
            netStatus = NetStatus.WIFI_CONNECTING_STATUS;
        }

        @Override
        public void connected() {
            netStatus = NetStatus.WIFI_CONNECTED_STATUS;
        }

        @Override
        public void disconnected() {
            preNetStatus = netStatus;
            netStatus = NetStatus.WIFI_DISCONNECTED_STATUS;
            if (preNetStatus != netStatus) {
                //mNetManager.stop();
                //checkWifi();
            }
        }

        @Override
        public void incorrect() {
            preNetStatus = netStatus;
            netStatus = NetStatus.WIFI_INCORRECT_STATUS;
            if (preNetStatus != netStatus) {
                //mNetManager.stop();
                checkWifi();
            }
        }

        @Override
        public void correct() {
            preNetStatus = netStatus;
            netStatus = NetStatus.WIFI_CORRECT_STATUS;
            if (preNetStatus != netStatus) {
                if (!mNetManager.isStarted()) {
                    // mNetManager.start();
                }
            }
            Intent intent1 = new Intent();
            intent1.setAction(Constants.WIFI_BORADCAST_ACTION);
            intent1.putExtra(Constants.BORADCAST_INTENT_OPTION, KEY_HANDLER_WIFI_CONNECT);
            sendBroadcast(intent1);
        }

        @Override
        public NetStatus getStatus() {
            return netStatus;
        }
    }

    /**
     * 网络状态变更的接口
     */
    private interface StateImp {
        /**
         * 用于组网状态标识：未开启，开启，连接中，已连接，未连接，连接到正确的网络，连接到不正确的网络
         */
        enum NetStatus {
            UNKNOWN_STATUS, WIFI_DISABLED_STATUS, WIFI_ENABLED_STATUS,
            WIFI_CONNECTING_STATUS, WIFI_CONNECTED_STATUS, WIFI_DISCONNECTED_STATUS,
            WIFI_INCORRECT_STATUS, WIFI_CORRECT_STATUS
        }

        void disabled();

        void enabled();

        void connecting();

        void connected();

        void disconnected();

        void incorrect();

        void correct();

        NetStatus getStatus();
    }
}
